import {HttpClient, HttpHeaders} from '@angular/common/http';
import {from, Observable, of} from 'rxjs';
import {tap} from 'rxjs/internal/operators';
import {Order, OrderToUpdate} from './order.model';
import {Inject, Injectable} from '@angular/core';
import {Washer} from '../../washers/shared/washer.model';
import {AuthHttp} from '../../shared/auth.http';
import {APP_CONFIG} from '../../config/app.config';

@Injectable()
export class OrderService {
  private baseUrl: string;
  private currentSelectedOrder: Order;

  get currentOrder(): Order {
    return this.currentSelectedOrder;
  }

  set currentOrder(currentOrder: Order ) {
    this.currentSelectedOrder = currentOrder;
  }

  public selectedValueStatusFilter: string;
  public inputValueUserMobileFilter: string;
  public inputValueOrderNumberFilter: string;

  constructor(@Inject(APP_CONFIG) appConfig,
              private http: AuthHttp) {
    this.baseUrl = appConfig.endpoints.base;
  }

  detectOrderListChange(originOrderIdList: number[], newOrderIdList: number[]) {
    const differences = [];
    originOrderIdList.forEach( elem => {
      if (newOrderIdList.indexOf(elem) < 0) {
        differences.push(elem);
      }
    });

    newOrderIdList.forEach( elem => {
      if (originOrderIdList.indexOf(elem) < 0) {
        differences.push(elem);
      }
    });
    return differences;
  }

  getOrderList(days: number): Observable<Order[]> {
    return this.http.get<Order[]>(this.baseUrl + 'be_apis/v2/order/listordersindays/' + days).pipe(
      tap( () => console.log('get order list successful...'),
        (err) => { console.error('get order list failed...'); console.error(err); })
    );
  }

  cancelOrder(orderNo: string, workerId: string): Observable<boolean> {
    return this.http.put<boolean>(this.baseUrl + 'be_ops/v2/worker/cancelorder/' + workerId + '/' + orderNo, null, null, 'text').pipe(
      tap(() => { console.log('cancel order succssful...'); },
        (err) => { console.error('cancel order failed...'); console.error(err); } )
    );
  }

  updateOrder(orderNo: string, order: Order): Observable<number> {
    const orderToUpdate = new OrderToUpdate(
      order.orderId,
      order.bookTime.toString().replace(' ', 'T'),
      // order.address,
      order.statusCode,
      order.price,
      order.license,
      order.discountedPrice,
      order.remarks
      );
    // let bookTimeString = orderToUpdate.bookTime.toString();
    // alert(bookTimeString.replace(' ', 'T'));
    let updatePriceProcess = false;
    if (order.newPrice && (order.newPrice !== order.discountedPrice)) { // determine the update price logic
      updatePriceProcess = true;
    }

    if (updatePriceProcess) {
      orderToUpdate.couponId = 0;
      orderToUpdate.promotionId = 0;
      orderToUpdate.operatorId = 1;
      orderToUpdate.discountedPrice = order.newPrice;
    }
    return this.http.put<number>(this.baseUrl + 'be_oms/v2/order/updateorder', orderToUpdate, null, 'text').pipe(
      tap(() => { console.log('update order succssful...'); },
        (err) => { console.error('update order failed...'); console.error(err); } )
    );
  }

  assignOrder(orderNo: string, realOrderNo: string,  washerIds: number[]): Observable<boolean> {
    console.log('inside assignOrder...');
    if (washerIds.length !== 1) {
      console.error('you must select ONLY ONE washer to dispatch...');
      return of(false);
    }
    const body = {orderId: orderNo, orderNumber: realOrderNo, workerId: washerIds[0]};
    return this.http.post<boolean>(this.baseUrl + 'be_ops/v2/worker/assignorder', body).pipe(
      tap(() => console.log('assign order successful...'),
        (err) => { console.error('assign order failed...'); console.error(err); })
    );
  }

  deleteOrder(orderNo: string): Observable<boolean> {
    console.log('inside deleteOrder...');
    return this.http.put<boolean>(this.baseUrl + 'be_oms/v2/order/delete/' + orderNo, null).pipe(
      tap(() => console.log('delete order successful...'),
        (err) => { console.error('delete order failed...'); console.error(err); })
    );
  }

  getOrderDetail(orderNo: string): Observable<Order> {
    console.log('inside getOrderDetail...');
    return this.http.get<Order>(this.baseUrl + 'be_apis/v2/order/detailwithwasher/' + orderNo).pipe(
      tap(() => console.log('get order detail successful...'),
        (err) => { console.error('get order detail failed...'); console.error(err); })
    );
  }

  getOrderAvailableWashers(orderNo: string): Observable<Washer[]> {
    return this.http.get<Washer[]>(this.baseUrl + 'be_ops/v2/worker/listall').pipe(
      tap(() => console.log('get order available washer list successful...'),
        (err) => { console.error('get order available wash list failed...'); console.error(err); })
    );
  }
}
